home *** CD-ROM | disk | FTP | other *** search
- /* SampleSelector.c */
- /*****************************************************************************/
- /* */
- /* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
- /* Copyright (C) 1994 Thomas R. Lawrence */
- /* */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to the Free Software */
- /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* */
- /* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
- /* */
- /*****************************************************************************/
-
- #include "MiscInfo.h"
- #include "Audit.h"
- #include "Debug.h"
- #include "Definitions.h"
-
- #include "SampleSelector.h"
- #include "Memory.h"
- #include "SampleList.h"
- #include "WaveTableList.h"
- #include "AlgoSampList.h"
- #include "AlgoWaveTableList.h"
-
-
- /* in the list, elements are cascaded as follows: */
- /* <lowestbound> <boundary2> <boundary3> <highestbound> */
- /* <sampname1> <sampname2> <sampname2> */
- struct SampleSelectorRec
- {
- /* number of RANGES (i.e. unique sample intervals) */
- long NumRanges;
-
- /* this is a list of the boundaries of the ranges, so there is one extra element */
- SampRangeHzType* BoundaryList; /* NumRanges + 1 elements */
-
- /* this is an array of sample names, one sample for each interval */
- char** SampleNameList; /* NumRanges elements */
-
- /* this is an array of sampled object references. it is not immediately valid */
- void** ReferencedObjectList; /* NumRanges elements */
-
- /* this is the type of object that is referenced */
- SampleSourceTypes* ReferencedObjectTypeList; /* NumRanges elements */
- };
-
-
- /* create a new sample selector record */
- SampleSelectorRec* NewSampleSelectorList(double LowestBound)
- {
- SampleSelectorRec* SampList;
-
- SampList = (SampleSelectorRec*)AllocPtrCanFail(sizeof(SampleSelectorRec),
- "SampleSelectorRec");
- if (SampList == NIL)
- {
- FailurePoint1:
- return NIL;
- }
- SampList->BoundaryList = (SampRangeHzType*)AllocPtrCanFail(
- 1 * sizeof(SampRangeHzType),"SampRangeHzType");
- if (SampList->BoundaryList == NIL)
- {
- FailurePoint2:
- ReleasePtr((char*)SampList);
- goto FailurePoint1;
- }
- SampList->BoundaryList[0] = LowestBound;
- SampList->SampleNameList = (char**)AllocPtrCanFail(0,"SampleNameList");
- if (SampList->SampleNameList == NIL)
- {
- FailurePoint3:
- ReleasePtr((char*)SampList->BoundaryList);
- goto FailurePoint2;
- }
- SampList->NumRanges = 0;
- SampList->ReferencedObjectList = NIL;
- SampList->ReferencedObjectTypeList = NIL;
- return SampList;
- }
-
-
- /* dispose of a sample selector list */
- void DisposeSampleSelectorList(SampleSelectorRec* SampList)
- {
- long Scan;
-
- CheckPtrExistence(SampList);
- for (Scan = 0; Scan < SampList->NumRanges; Scan += 1)
- {
- ReleasePtr(SampList->SampleNameList[Scan]);
- }
- if (SampList->ReferencedObjectList != NIL)
- {
- ReleasePtr((char*)SampList->ReferencedObjectList);
- }
- if (SampList->ReferencedObjectTypeList != NIL)
- {
- ReleasePtr((char*)SampList->ReferencedObjectTypeList);
- }
- ReleasePtr((char*)SampList->SampleNameList);
- ReleasePtr((char*)SampList->BoundaryList);
- ReleasePtr((char*)SampList);
- }
-
-
- /* add a new sample thing, with it's upper bound. the object becomes the */
- /* owner of the name string */
- MyBoolean AppendSampleSelector(SampleSelectorRec* SampList,
- double UpperBound, char* Name)
- {
- SampRangeHzType* NewBoundaryList;
- char** NewNameList;
-
- CheckPtrExistence(SampList);
- CheckPtrExistence(Name);
- NewBoundaryList = (SampRangeHzType*)ResizePtr((char*)SampList->BoundaryList,
- sizeof(SampRangeHzType) * (1 + 1 + SampList->NumRanges));
- if (NewBoundaryList == NIL)
- {
- return False;
- }
- NewNameList = (char**)ResizePtr((char*)SampList->SampleNameList,
- sizeof(char*) * (1 + SampList->NumRanges));
- /* if this fails, we don't do any cleanup because it doesn't matter if the */
- /* size of the array is a bit long -- the size is really determined by NumRanges */
- if (NewNameList == NIL)
- {
- return False;
- }
- SampList->BoundaryList = NewBoundaryList;
- SampList->SampleNameList = NewNameList;
- SampList->BoundaryList[SampList->NumRanges + 1] = UpperBound;
- SampList->SampleNameList[SampList->NumRanges] = Name;
- SampList->NumRanges += 1;
- return True;
- }
-
-
- /* get the number of sample ranges specified in the list */
- long GetSampleSelectorListLength(SampleSelectorRec* SampList)
- {
- CheckPtrExistence(SampList);
- return SampList->NumRanges;
- }
-
-
- /* return the low bound frequency of a particular list entry */
- SampRangeHzType GetSampleListEntryLowFreqBound(SampleSelectorRec* SampList,
- long Index)
- {
- CheckPtrExistence(SampList);
- ERROR((Index < 0) || (Index >= SampList->NumRanges),PRERR(ForceAbort,
- "GetSampleListEntryLowFreqBound: index is out of range"));
- PRNGCHK(SampList->BoundaryList,&(SampList->BoundaryList[Index]),
- sizeof(SampList->BoundaryList[Index]));
- return SampList->BoundaryList[Index];
- }
-
-
- /* return the high bound frequency of a particular list entry */
- SampRangeHzType GetSampleListEntryHighFreqBound(SampleSelectorRec* SampList,
- long Index)
- {
- CheckPtrExistence(SampList);
- ERROR((Index < 0) || (Index >= SampList->NumRanges),PRERR(ForceAbort,
- "GetSampleListEntryHighFreqBound: index is out of range"));
- PRNGCHK(SampList->BoundaryList,&(SampList->BoundaryList[Index + 1]),
- sizeof(SampList->BoundaryList[Index + 1]));
- return SampList->BoundaryList[Index + 1];
- }
-
-
- /* get the actual ptr to the sample name */
- char* GetSampleListEntryName(SampleSelectorRec* SampList, long Index)
- {
- CheckPtrExistence(SampList);
- ERROR((Index < 0) || (Index >= SampList->NumRanges),PRERR(ForceAbort,
- "GetSampleListEntryName: index is out of range"));
- PRNGCHK(SampList->SampleNameList,&(SampList->SampleNameList[Index]),
- sizeof(SampList->SampleNameList[Index]));
- return SampList->SampleNameList[Index];
- }
-
-
- /* resolve named references to samples. returns False if it can't */
- MyBoolean ResolveSamplesInSampleList(SampleSelectorRec* SampList,
- struct SampleListRec* SampleList,
- struct AlgoSampListRec* AlgoSampList)
- {
- long Scan;
-
- CheckPtrExistence(SampList);
- CheckPtrExistence(SampleList);
- CheckPtrExistence(AlgoSampList);
- ERROR(SampList->ReferencedObjectList != NIL,PRERR(ForceAbort,
- "ResolveSamplesInSampleList: ReferencedObjectList is not NIL"));
- ERROR(SampList->ReferencedObjectTypeList != NIL,PRERR(ForceAbort,
- "ResolveSamplesInSampleList: ReferencedObjectTypeList is not NIL"));
-
- SampList->ReferencedObjectList = (void**)AllocPtrCanFail(SampList->NumRanges
- * sizeof(void*),"SampleSelectorRec: ReferencedObjectList");
- if (SampList->ReferencedObjectList == NIL)
- {
- FailurePoint1:
- return False;
- }
- SampList->ReferencedObjectTypeList = (SampleSourceTypes*)AllocPtrCanFail(
- SampList->NumRanges * sizeof(SampleSourceTypes),
- "SampleSelectorRec: ReferencedObjectTypeList");
- if (SampList->ReferencedObjectTypeList == NIL)
- {
- FailurePoint2:
- ReleasePtr((char*)SampList->ReferencedObjectList);
- SampList->ReferencedObjectList = NIL;
- goto FailurePoint1;
- }
-
- for (Scan = 0; Scan < SampList->NumRanges; Scan += 1)
- {
- PRNGCHK(SampList->SampleNameList,&(SampList->SampleNameList[Scan]),
- sizeof(SampList->SampleNameList[Scan]));
- SampList->ReferencedObjectList[Scan] = SampleListLookupNamedSample(
- SampleList,SampList->SampleNameList[Scan]);
- if (SampList->ReferencedObjectList[Scan] != NIL)
- {
- SampList->ReferencedObjectTypeList[Scan] = eDataSample;
- }
- else
- {
- SampList->ReferencedObjectList[Scan] = AlgoSampListLookupNamedAlgoSamp(
- AlgoSampList,SampList->SampleNameList[Scan]);
- if (SampList->ReferencedObjectList[Scan] != NIL)
- {
- SampList->ReferencedObjectTypeList[Scan] = eAlgoSample;
- }
- else
- {
- return False;
- }
- }
- }
-
- return True;
- }
-
-
- /* resolve named references to wave tables. returns False if it can't */
- MyBoolean ResolveWaveTablesInSampleList(SampleSelectorRec* SampList,
- struct WaveTableListRec* WaveTableList,
- struct AlgoWaveTableListRec* AlgoWaveTableList)
- {
- long Scan;
-
- CheckPtrExistence(SampList);
- CheckPtrExistence(WaveTableList);
- CheckPtrExistence(AlgoWaveTableList);
- ERROR(SampList->ReferencedObjectList != NIL,PRERR(ForceAbort,
- "ResolveWaveTablesInSampleList: ReferencedObjectList is not NIL"));
- ERROR(SampList->ReferencedObjectTypeList != NIL,PRERR(ForceAbort,
- "ResolveWaveTablesInSampleList: ReferencedObjectTypeList is not NIL"));
-
- SampList->ReferencedObjectList = (void**)AllocPtrCanFail(SampList->NumRanges
- * sizeof(void*),"SampleSelectorRec: ReferencedObjectList");
- if (SampList->ReferencedObjectList == NIL)
- {
- FailurePoint1:
- return False;
- }
- SampList->ReferencedObjectTypeList = (SampleSourceTypes*)AllocPtrCanFail(
- SampList->NumRanges * sizeof(SampleSourceTypes),
- "SampleSelectorRec: ReferencedObjectTypeList");
- if (SampList->ReferencedObjectTypeList == NIL)
- {
- FailurePoint2:
- ReleasePtr((char*)SampList->ReferencedObjectList);
- SampList->ReferencedObjectList = NIL;
- goto FailurePoint1;
- }
-
- for (Scan = 0; Scan < SampList->NumRanges; Scan += 1)
- {
- PRNGCHK(SampList->SampleNameList,&(SampList->SampleNameList[Scan]),
- sizeof(SampList->SampleNameList[Scan]));
- SampList->ReferencedObjectList[Scan] = WaveTableListLookupNamedWaveTable(
- WaveTableList,SampList->SampleNameList[Scan]);
- if (SampList->ReferencedObjectList[Scan] != NIL)
- {
- SampList->ReferencedObjectTypeList[Scan] = eDataWaveTable;
- }
- else
- {
- SampList->ReferencedObjectList[Scan]
- = AlgoWaveTableListLookupNamedAlgoWaveTable(AlgoWaveTableList,
- SampList->SampleNameList[Scan]);
- if (SampList->ReferencedObjectList[Scan] != NIL)
- {
- SampList->ReferencedObjectTypeList[Scan] = eAlgoWaveTable;
- }
- else
- {
- return False;
- }
- }
- }
-
- return True;
- }
-
-
- /* get the wave type of an entry */
- SampleSourceTypes GetSampleListWaveType(SampleSelectorRec* SampList,
- long Index)
- {
- CheckPtrExistence(SampList);
- ERROR(SampList->ReferencedObjectTypeList == NIL,PRERR(ForceAbort,
- "GetSampleListWaveType: type list is NIL (refs haven't been resolved yet)"));
- CheckPtrExistence(SampList->ReferencedObjectTypeList);
- ERROR((Index < 0) || (Index >= SampList->NumRanges),PRERR(ForceAbort,
- "GetSampleListWaveType: index out of range"));
- PRNGCHK(SampList->ReferencedObjectTypeList,
- &(SampList->ReferencedObjectTypeList[Index]),
- sizeof(SampList->ReferencedObjectTypeList[Index]));
- return SampList->ReferencedObjectTypeList[Index];
- }
-
-
- /* get a reference to the object */
- void* GetSampleListWaveReference(SampleSelectorRec* SampList,
- long Index)
- {
- CheckPtrExistence(SampList);
- ERROR(SampList->ReferencedObjectList == NIL,PRERR(ForceAbort,
- "GetSampleListWaveReference: type list is NIL (refs haven't been resolved yet)"));
- CheckPtrExistence(SampList->ReferencedObjectList);
- ERROR((Index < 0) || (Index >= SampList->NumRanges),PRERR(ForceAbort,
- "GetSampleListWaveReference: index out of range"));
- PRNGCHK(SampList->ReferencedObjectList,&(SampList->ReferencedObjectList[Index]),
- sizeof(SampList->ReferencedObjectList[Index]));
- return SampList->ReferencedObjectList[Index];
- }
-